package service

import (
	"errors"
	"github.com/go-admin-team/go-admin-core/sdk/service"
	"gorm.io/gorm"
	"strconv"
	"strings"
	"tuowei.com/app/admin/models"
	"tuowei.com/app/admin/service/dto"
	"tuowei.com/common/actions"
	cDto "tuowei.com/common/dto"
	"tuowei.com/pkg/xlog"
)

type SysQuestionBank struct {
	service.Service
}

// GetPage 获取SysExercise列表
func (e *SysQuestionBank) GetPage(c *dto.SysQuestionBankGetPageReq, p *actions.DataPermission, list *[]models.SysQuestionBank, count *int64) error {
	var err error
	var data models.SysQuestionBank

	err = e.Orm.Debug().
		Scopes(
			cDto.MakeCondition(c.GetNeedSearch()),
			cDto.Paginate(c.GetPageSize(), c.GetPageIndex()),
			actions.Permission(data.TableName(), p),
		).Order("id desc").
		Find(list).Limit(-1).Offset(-1).
		Count(count).Error
	if err != nil {
		e.Log.Errorf("db error: %s", err)
		return err
	}
	return nil
}

// Insert 创建SysExercise对象
func (e *SysQuestionBank) Insert(c *dto.SysQuestionBankInsertReq) error {
	var err error
	var data models.SysQuestionBank
	c.Generate(&data)
	err = e.Orm.Create(&data).Error
	if err != nil {
		return err
	}
	return nil
}

func (e *SysQuestionBank) Update(c *dto.SysQuestionBankUpdateReq) error {
	var err error
	var model = models.SysQuestionBank{}

	e.Orm.First(&model, c.GetId())
	c.Generate(&model)
	db := e.Orm.Save(&model)
	err = db.Error
	if err != nil {
		e.Log.Errorf("Service UpdateStatus error:%s", err)
		return err
	}
	if db.RowsAffected == 0 {
		return errors.New("无权更新该数据")

	}
	return nil
}

// Remove 删除SysExercise
func (e *SysQuestionBank) Remove(c *dto.SysQuestionBankById, p *actions.DataPermission) error {
	var err error
	var data models.SysQuestionBank
	db := e.Orm.Model(&data).
		Scopes(
			actions.Permission(data.TableName(), p),
		).Delete(&data, c.GetId())
	if err = db.Error; err != nil {
		xlog.Errorf("Error found in  RemoveSysCourse : %s", err)
		return err
	}
	if db.RowsAffected == 0 {
		return errors.New("无权删除该数据")
	}

	return nil

}

// Get 获取SysExercise对象
func (e *SysQuestionBank) Get(d *dto.SysQuestionBankById, p *actions.DataPermission, model *models.SysQuestionBank) error {
	var data models.SysQuestionBank

	err := e.Orm.Model(&data).Debug().
		Scopes(
			actions.Permission(data.TableName(), p),
		).
		First(model, d.GetId()).Error

	if err != nil && errors.Is(err, gorm.ErrRecordNotFound) {
		err = errors.New("查看对象不存在或无权查看")
		xlog.Errorf("db error: %s", err)
		return err
	}

	return nil
}

func (e *SysQuestionBank) SaveSelectedQuestionBank(c *dto.SaveSelectedQuestionBankReq) error {
	var data models.SysQuestionBankLink
	var model models.SysQuestionBankLink
	var examinationData models.SysExamination
	var courseWare models.SysCourseWare
	var exercisesWare models.SysExercisesWare

	arr := strings.Split(c.QuestionBankStr, ",")
	intArr := make([]int, 0)
	for _, v := range arr {
		v, _ := strconv.Atoi(v)
		intArr = append(intArr, v)
	}
	count := len(intArr)
	db := e.Orm.Model(&model).Where("link_id = ?", c.LinkId).
		Where("link_type = ?", c.LinkType)
	if c.ChapterId != 0 {
		db = db.Where("chapter_id = ?", c.ChapterId)
	}
	err := db.First(&data).Error

	if err != nil && errors.Is(err, gorm.ErrRecordNotFound) {
		return e.Orm.Debug().Transaction(func(tx *gorm.DB) error {
			c.Generate(&data)
			err = tx.Create(&data).Error
			if err != nil {
				xlog.Error("=====", err.Error())
				return err
			}
			isContainExercise := 0
			if count > 0 {
				isContainExercise = 1
			} else {
				isContainExercise = -1
			}
			if c.LinkType == 1 {
				var datas models.SysCourseWare
				err = e.Orm.Debug().Where("id = ?", c.ChapterId).First(&datas).Error

				if err != nil {
					return err
				}
				updates := map[string]interface{}{"is_contain_exercise": isContainExercise, "count": count}
				err = tx.Model(courseWare).Where("id = ?", c.ChapterId).Updates(updates).Error
				if err != nil {
					xlog.Error("=====", err.Error())
					return err
				}

				return nil
			} else if c.LinkType == 2 {
				var datas models.SysExercisesWare
				err = e.Orm.Debug().Where("id = ?", c.ChapterId).First(&datas).Error
				if err != nil {
					return err
				}
				updates := map[string]interface{}{"is_contain_exercise": isContainExercise, "count": count}
				err = tx.Model(exercisesWare).Where("id = ?", c.ChapterId).Updates(updates).Error
				if err != nil {
					return err
				}
				return nil
			} else if c.LinkType == 3 {
				var examination models.SysExamination
				updates := map[string]interface{}{"count": count}
				err = tx.Model(examination).Where("id = ?", c.LinkId).Updates(updates).Error
				if err != nil {
					return err
				}
				return nil
			}

			return nil
		})
	} else {

		return e.Orm.Transaction(func(tx *gorm.DB) error {
			var saveData models.SysQuestionBankLink
			c.Generate(&saveData)
			saveData.Id = data.Id
			err = tx.Save(&saveData).Error
			if err != nil {
				return err
			}

			if c.LinkType == 1 {
				err = tx.Model(&courseWare).Where("id = ?", c.LinkId).Update("count", count).Error
				if err != nil {
					return err
				}
			} else if c.LinkType == 2 {
				err = tx.Model(&exercisesWare).Where("id = ?", c.LinkId).Update("count", count).Error
				if err != nil {
					return err
				}
			} else if c.LinkType == 3 {
				err = tx.Model(&examinationData).Where("id = ?", c.LinkId).Update("count", count).Error
				if err != nil {
					return err
				}
			}

			return nil
		})
	}

}

func (e *SysQuestionBank) GetQuestionBankList(c *dto.SysQuestionBankListByIDS) (list []*models.SysQuestionBank, err error) {
	var data models.SysQuestionBankLink
	var questionBank models.SysQuestionBank
	err = e.Orm.Model(&data).
		Scopes(
			cDto.MakeCondition(c.GetNeedSearch()),
		).First(&data).Error
	if err != nil && errors.Is(err, gorm.ErrRecordNotFound) {
		xlog.Errorf("db error: %s", err)
		return nil, err
	}
	arr := strings.Split(data.QuestionBankStr, ",")
	intArr := make([]int, 0)
	for _, v := range arr {
		v, _ := strconv.Atoi(v)
		intArr = append(intArr, v)
	}
	list = make([]*models.SysQuestionBank, 0)
	err = e.Orm.Model(&questionBank).Where("id in ?", intArr).Find(&list).Error
	if err != nil {
		return nil, err
	}
	return list, nil
}
